
/* scenegraph.cpp: Functions for creating and managing the scenegraph. */

#include<osg/Node>
#include<osg/Geode>
#include<osg/Geometry>
#include<osg/MatrixTransform>
#include<osg/NodeCallback>
#include<osg/Notify>
#include<osg/Timer>
#include<osg/LineWidth>
#include<osgText/Font>
#include<osgText/Text>
#include<vector>
#include<sstream>
#include<iostream>
#include<cmath>
#include "scenegraph.h"
#include "global.h"

#ifdef _MSC_VER
   #define _USE_MATH_DEFINES
#endif

using namespace std;

osg::ref_ptr<osgText::Text> create_text(int value, double x)
{
	osg::ref_ptr<osgText::Text> text = new osgText::Text;
	osg::ref_ptr<osgText::Font> font = osgText::readFontFile("fonts/arial.ttf");

	/* Convert value of the key to string. */
	stringstream out;
	out << value;

	text->setFont(font.get());
	text->setFontResolution(128, 128);
	text->setText(osgText::String(out.str()));

	text->setPosition(osg::Vec3(x, 0.0, 4.0));
	cout << "x  = " << x << endl;

	text->setAxisAlignment(osgText::Text::SCREEN);
	text->setAlignment(osgText::Text::CENTER_CENTER);
	text->setCharacterSize(0.6);
	// Label color is always BLACK
	text->setColor(osg::Vec4(0.0, 0.0, 0.0, 1.0));
	
	return text.get();
}

osg::ref_ptr<osg::Geode> draw_input(DataContainer& input)
{
    osg::ref_ptr<osg::Geode> geode = new osg::Geode;

	double x = -(double)input.size()+1;
	for(int i = 0; i < (int)input.size(); i++) {

		osg::ref_ptr<osgText::Text> text = create_text(input[i], x);
		// Later use value of i as index to access drawable obj.
		geode->addDrawable(text.get());
		x = x + 2.0;
	}

	return geode.get();
}

/* Create circle in XZ plane. */
#define POLYGON_SIZE 256
osg::ref_ptr<osg::Geometry> create_circle(float centerx, float centerz, float rad)
{
	osg::ref_ptr<osg::Geometry> geom = new osg::Geometry;
	osg::ref_ptr<osg::Vec3Array> v = new osg::Vec3Array;
	double theta, px, pz;

	for(int i = 1; i <= POLYGON_SIZE; i++) {

		theta = 2.0 * M_PI/POLYGON_SIZE * i;
		px = centerx + rad * cos(theta);
		pz = centerz + rad * sin(theta);
		v->push_back(osg::Vec3(px, 0, pz));
	}

 	geom->setVertexArray( v.get() );
	geom->addPrimitiveSet(
		new osg::DrawArrays( osg::PrimitiveSet::POLYGON, 0, POLYGON_SIZE) );

	osg::StateSet* stateset = new osg::StateSet;
	osg::LineWidth* linewidth = new osg::LineWidth();

	linewidth->setWidth(2.0f);
	stateset->setAttributeAndModes(linewidth,osg::StateAttribute::ON);
	geom->setStateSet(stateset);

	return geom.get();
}

/* Create Line in XZ plane. */
osg::ref_ptr<osg::Geometry> create_line(float x1, float z1, float x2, float z2)
{
    osg::ref_ptr<osg::Geometry> geom = new osg::Geometry;
    osg::ref_ptr<osg::Vec3Array> v = new osg::Vec3Array;

    v->push_back( osg::Vec3(x1, 0, z1) );
    v->push_back( osg::Vec3(x2, 0, z2) );

    geom->setVertexArray( v.get() );
    geom->addPrimitiveSet(
        new osg::DrawArrays( osg::PrimitiveSet::LINES, 0, 2 ) );

    osg::StateSet* stateset = new osg::StateSet;
    osg::LineWidth* linewidth = new osg::LineWidth();

    linewidth->setWidth(1.0f);
    stateset->setAttributeAndModes(linewidth,osg::StateAttribute::ON);
    geom->setStateSet(stateset);

    return geom.get();
}

